package com.xingkeduo.dao.database.mysql.config;

import java.sql.SQLException;

import javax.sql.DataSource;

import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.SqlSessionTemplate;
import org.mybatis.spring.boot.autoconfigure.SpringBootVFS;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Conditional;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.core.io.support.ResourcePatternResolver;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;

import com.alibaba.druid.pool.DruidDataSource;
import com.xingkeduo.dao.database.DatabaseAccessObject;
import com.xingkeduo.dao.database.DatabaseProxy;
import com.xingkeduo.dao.database.mysql.condition.MysqlUserMasterCondition;
import com.xingkeduo.util.pojo.base.BaseQuery;
import com.xingkeduo.util.pojo.base.BaseTable;

@Configuration
@Conditional(MysqlUserMasterCondition.class)
public class MysqlUserMasterConfig<T extends BaseTable<T>, Q extends BaseQuery<Q>> {
	@Value("${db.mysql.user.driver}")
	private String driver;
	@Value("${db.mysql.user.url}")
	private String url;
	@Value("${db.mysql.user.user}")
	private String user;
	@Value("${db.mysql.user.password}")
	private String password;
	@Value("${db.mysql.user.maxActive}")
	private int maxActive;
	@Value("${db.mysql.user.initialSize}")
	private int initialSize;
	@Value("${db.mysql.user.maxWait}")
	private long maxWait;
	@Value("${db.mysql.user.minIdle}")
	private int minIdle;

	@Bean(name = "mysqlUserMasterDataSource")
	public DataSource initDataSource() throws SQLException {
		DruidDataSource dataSource = new DruidDataSource();
		dataSource.setDriverClassName(driver);
		dataSource.setUrl(url);
		dataSource.setUsername(user);
		dataSource.setPassword(password);
		dataSource.setFilters("stat");// 监控数据库
		dataSource.setMaxActive(maxActive);// 连接池最大使用连接数量
		dataSource.setInitialSize(initialSize);// 初始化连接大小
		dataSource.setMaxWait(maxWait);// 获取连接最大等待时间，单位是毫秒
		dataSource.setMinIdle(minIdle);// 连接池最小空闲连接数量
		dataSource.setTimeBetweenEvictionRunsMillis(60000);// 配置间隔多久才进行一次检测，检测需要关闭的空闲连接，单位是毫秒
		dataSource.setMinEvictableIdleTimeMillis(300000);// 配置一个连接在池中最小生存的时间，单位是毫秒
		dataSource.setRemoveAbandoned(true);// 打开removeAbandoned功能
		dataSource.setRemoveAbandonedTimeout(1800);// removeAbandoned超时时间，单位是秒
		dataSource.setLogAbandoned(true);// 关闭abanded连接时输出错误日志
		dataSource.setValidationQuery("SELECT 'x'");
		dataSource.setTestWhileIdle(true);
		dataSource.setTestOnBorrow(false);
		dataSource.setTestOnReturn(false);
		dataSource.setPoolPreparedStatements(true);
		dataSource.setMaxPoolPreparedStatementPerConnectionSize(50);

		return dataSource;
	}

	@Bean(name = "mysqlUserMasterTransactionManager")
	public DataSourceTransactionManager initTransactionManager() {
		try {
			return new DataSourceTransactionManager(initDataSource());
		} catch (SQLException e) {
			e.printStackTrace();
			return null;
		}
	}

	@Bean(name = "mysqlUserMasterSqlSessionFactory")
	public SqlSessionFactory initSqlSessionFactory(@Qualifier("mysqlUserMasterDataSource") DataSource dataSource)
			throws Exception {
		ResourcePatternResolver resolver = new PathMatchingResourcePatternResolver();

		SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
		sqlSessionFactoryBean.setDataSource(dataSource);
		sqlSessionFactoryBean.setTypeAliasesPackage("com.xingkeduo.pojo.table,com.xingkeduo.pojo.query");
		sqlSessionFactoryBean.setMapperLocations(resolver.getResources("classpath:mapper/*.xml"));
		sqlSessionFactoryBean.setConfigLocation(resolver.getResource("classpath:mybatis.xml"));
		sqlSessionFactoryBean.setVfs(SpringBootVFS.class);

		return sqlSessionFactoryBean.getObject();
	}

	@Bean(name = "mysqlUserMasterSqlSessionTemplateFromMybatis")
	public SqlSessionTemplate initSqlSessionTemplate(
			@Qualifier("mysqlUserMasterSqlSessionFactory") SqlSessionFactory sqlSessionFactory) {
		return new SqlSessionTemplate(sqlSessionFactory);
	}

	@Bean(name = "mysqlUserMasterDao")
	public DatabaseAccessObject<T, Q> initMysqlUserMasterDao(
			@Qualifier("mysqlUserMasterSqlSessionTemplateFromMybatis") SqlSessionTemplate sqlSessionTemplate) {
		return new DatabaseProxy<T, Q>().build(sqlSessionTemplate);
	}
}
